package com.huan.es8.aggregations.pipeline;

import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.mapping.*;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.util.NamedValue;
import com.huan.es8.AbstractEs8Api;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;

/**
 * bucket_script聚合操作
 * <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline.html#buckets-path-syntax">官方文档</a>
 * <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-script-aggregation.html">官方文档</a>
 * <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/text/DecimalFormat.html">官方文档</a>
 * <a href="https://blog.csdn.net/fu_huo_1993/article/details/128883683">博客</a>
 *
 * @author huan.fu
 * @date 2023/2/4 - 15:32
 */
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class BucketScript统计宝马车每个月销售率 extends AbstractEs8Api {

    public static final String INDEX_NAME = "index_bucket_script";

    @BeforeAll
    public void setUp() throws IOException {
        client.indices()
                .create(indexRequest ->
                        indexRequest.index("index_person")
                                .mappings(mappings ->
                                        mappings.properties("month", new Property(new KeywordProperty.Builder().build()))
                                                .properties("brand", new Property(new KeywordProperty.Builder().build()))
                                                .properties("salesVolume", new Property(new IntegerNumberProperty.Builder().build()))
                                )
                );
        bulk("index_person", Arrays.asList(
                "{\"month\":\"2023-01\",\"brand\":\"宝马\",\"salesVolume\":100}",
                "{\"month\":\"2023-02\",\"brand\":\"大众\",\"salesVolume\":80}",
                "{\"month\":\"2023-02\",\"brand\":\"宝马\",\"salesVolume\":20}"
        ));
    }

    @Test
    @DisplayName("统计宝马车每个月销售率")
    public void test01() throws IOException {
        SearchRequest request = SearchRequest.of(searchRequest ->
                searchRequest.index(INDEX_NAME)
                        .query(query -> query.matchAll(matchAll -> matchAll))
                        .size(0)
                        .aggregations("根据月份分组", monthAggr ->
                                monthAggr.terms(terms -> terms.field("month").order(
                                                NamedValue.of("_key", SortOrder.Asc)
                                        ))
                                        .aggregations("统计每个月卖了多少辆车", agg1 ->
                                                agg1.sum(sum -> sum.field("salesVolume"))
                                        )
                                        .aggregations("统计每个月卖了多少宝马车", agg2 ->
                                                agg2.filter(filter -> filter.term(term -> term.field("brand").value("宝马")))
                                                        .aggregations("每个月卖出的宝马车辆数", agg3 ->
                                                                agg3.sum(sum -> sum.field("salesVolume"))
                                                        )
                                        )
                                        .aggregations("每个月宝马车销售占比", rateAggr ->
                                                rateAggr.bucketScript(bucketScript ->
                                                        bucketScript.bucketsPath(path ->
                                                                        path.dict(
                                                                                new HashMap<String, String>() {
                                                                                    {
                                                                                        put("fenzi", "统计每个月卖了多少宝马车>每个月卖出的宝马车辆数");
                                                                                        put("fenmu", "统计每个月卖了多少辆车");
                                                                                    }
                                                                                }
                                                                        )

                                                                )
                                                                .script(script ->
                                                                        script.inline(inline -> inline.source("params.fenzi/params.fenmu"))
                                                                )
                                                                // 参考DecimalFormat类
                                                                .format("#%")
                                                )
                                        )
                        )
        );
        System.out.println("request: " + request);
        SearchResponse<String> response = client.search(request, String.class);
        System.out.println("response: " + response);
    }

    @Test
    public void tearDown() throws IOException {
        deleteIndex(INDEX_NAME);
    }

}
